package com.qingsong.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.core.relation.RelationManager;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.qingsong.dto.CartInsertDTO;
import com.qingsong.dto.CartPageDTO;
import com.qingsong.dto.CartUpdateDTO;
import com.qingsong.entity.Cart;
import com.qingsong.entity.Course;
import com.qingsong.entity.User;
import com.qingsong.feign.CourseFeign;
import com.qingsong.feign.UserFeign;
import com.qingsong.mapper.CartMapper;
import com.qingsong.result.Result;
import com.qingsong.service.CartService;
import com.qingsong.vo.CartSimpleListVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;

import static com.qingsong.entity.table.CartTableDef.CART;

/**
 * 购物车表 服务层实现。
 *
 * @author qingsong
 * @since 2024-12-22
 */
@Service
@CacheConfig(cacheNames = "cart")
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart>  implements CartService{


    @Autowired
    private UserFeign userFeign;

    @Autowired
    private CourseFeign courseFeign;

    @CacheEvict(allEntries = true)
    @Override
    public boolean insert(CartInsertDTO dto) {
        // 组装 entity 实体类
        Cart cart = BeanUtil.copyProperties(dto, Cart.class);
        User user = userFeign.select(dto.getFkUserId()).getData();
        Course course = courseFeign.select(dto.getFkCourseId()).getData();
        if(ObjectUtil.isNull(user)){
            throw new RuntimeException("用户不存在");
        }
        if(ObjectUtil.isNull(course)){
            throw new RuntimeException("课程不存在");
        }
        // 检查购物车记录是否已存在
        boolean exists = QueryChain.of(mapper)
                .eq("fk_user_id", dto.getFkUserId())
                .eq("fk_course_id", dto.getFkCourseId())
                .exists();

        if (exists) {
            throw new RuntimeException("购物车记录已存在");
        }
        cart.setCourseTitle(course.getTitle());
        cart.setCoursePrice(course.getPrice());
        cart.setCourseCover(course.getCover());
        cart.setUsername(user.getUsername());
        cart.setCreated(LocalDateTime.now());
        cart.setUpdated(LocalDateTime.now());
        return mapper.insert(cart) > 0;
    }

    @Cacheable(key = "#p0", condition = "#p0 != null", unless = "#result == null")
    @Override
    public Cart select(Long id) {
        RelationManager.addQueryRelations("user", "course");
        return mapper.selectOneWithRelationsById(id);
    }

    @Cacheable(key = "#root.methodName", unless = "#result == null")
    @Override
    public List<CartSimpleListVO> simpleList() {
        return QueryChain.of(mapper)
                .withRelations()
                .listAs(CartSimpleListVO.class);
    }

    @Cacheable(key = "#root.methodName + ':' + #p0.toString()", condition = "#p0 != null", unless = "#result == null")
    @Override
    public Page<Cart> page(CartPageDTO dto) {
        QueryChain<Cart> queryChain = QueryChain.of(mapper);
        // fkUserId条件
        Long fkUserId = dto.getFkUserId();
        if (ObjectUtil.isNotNull(fkUserId)) {
            queryChain.where(CART.FK_USER_ID.eq(fkUserId));
        }
        // fkCourseId 条件
        Long fkCourseId = dto.getFkCourseId();
        if (ObjectUtil.isNotNull(fkCourseId)) {
            queryChain.where(CART.FK_COURSE_ID.eq(fkCourseId));
        }
        // courseTitle 条件
        String courseTitle = dto.getCourseTitle();
        if (ObjectUtil.isNotNull(courseTitle)) {
            queryChain.where(CART.COURSE_TITLE.like(courseTitle));
        }
        return queryChain.withRelations().page(new Page<>(dto.getPageNum(), dto.getPageSize()));
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(CartUpdateDTO dto) {
        // 组装 entity 实体类
        Cart cart = BeanUtil.copyProperties(dto, Cart.class);
        Result<User> user = userFeign.select(dto.getFkUserId());
        Result<Course> course = courseFeign.select(dto.getFkCourseId());
        if(ObjectUtil.isNull(user)){
            throw new RuntimeException("用户不存在");
        }
        if(ObjectUtil.isNull(course)){
            throw new RuntimeException("课程不存在");
        }
        if(ObjectUtil.isNull(cart)){
            throw new RuntimeException("购物车记录不存在");
        }
        cart.setUsername(user.getData().getUsername());
        cart.setCourseTitle(course.getData().getTitle());
        cart.setCourseCover(course.getData().getCover());
        cart.setCoursePrice(course.getData().getPrice());
        cart.setUpdated(LocalDateTime.now());
        return UpdateChain.of(cart).where(CART.ID.eq(cart.getId())).update();
    }
    @CacheEvict(allEntries = true)
    @Override
    public Double totalAmountByUserId(Long id) {
        // SELECT course_price FROM cart WHERE fk_user_id = ?
        List<Cart> A =  QueryChain.of(mapper)
                .select(CART.COURSE_PRICE)
                .where(CART.FK_USER_ID.eq(id))
                .list();
        double total = 0.0;
        for (Cart item : A) {
            total += item.getCoursePrice();
        }
        return total;

    }
    @CacheEvict(allEntries = true)
    @Override
    public boolean cleanByUserId(Long id) {
        // DELETE FROM cart WHERE fk_user_id = ?;
        return UpdateChain.of(mapper)
                .where(CART.FK_USER_ID.eq(id))
                .remove();
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean delete(Long id) {
        return mapper.deleteById(id) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteBatch(List<Long> ids) {
        return mapper.deleteBatchByIds(ids) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean deleteByUserIdAndCourseIds(Long userId, List<Long> courseIds) {
        return UpdateChain.of(mapper)
                .where(CART.FK_USER_ID.eq(userId))
                .and(CART.FK_COURSE_ID.in(courseIds))
                .remove();
    }
}
